package com.rmkj.trade.match.core;

import com.rmkj.trade.match.util.MyLog;

import java.util.*;

/**
 * Created by Administrator on 2019/1/8.
 */
public abstract class AbstractDefaultOrderStore implements OrderStore, OrderPersistence {

	private final static MyLog _log = MyLog.getLog(AbstractDefaultOrderStore.class);

	Comparator comparatorSell = (Comparator<Order>) (o1, o2) -> {
		double diff = Double.parseDouble(o1.getPrice()) - Double.parseDouble(o2.getPrice());
		return diff == 0 ? 0 : (diff > 0 ? 1 : -1);
	};

	Comparator comparatorBuy = (Comparator<Order>) (o1, o2) -> {
		double diff = Double.parseDouble(o2.getPrice()) - Double.parseDouble(o1.getPrice());
		return diff == 0 ? 0 : (diff > 0 ? 1 : -1);
	};

	private Set<Order> sell = new TreeSet(comparatorSell);
	private Set<Order> buy = new TreeSet(comparatorBuy);

	private LinkedList<Order> history = new LinkedList();
	private LinkedList<OrderPairs> pairses = new LinkedList<>();

	private LinkedList<Order> sellTemp = new LinkedList();
	private LinkedList<Order> buyTemp = new LinkedList();

	private final Object lock1 = new Object();
	private final Object lock2 = new Object();

	@Override
	public boolean put(Order order) {
		synchronized (lock2) {
			boolean r = false;
			// 交给撮合人校验order
			if(MatchTradeConstants.ORDER_DIRECTION_SELL == order.getDirection()){
				r =  sellTemp.add(order);
			}else if(MatchTradeConstants.ORDER_DIRECTION_BUY == order.getDirection()){
				r =  buyTemp.add(order);
			}
			return r;
		}
	}

	@Override
	public void putReal() {
		synchronized (lock2) {
			synchronized (lock1) {
				sell.addAll(sellTemp);
				buy.addAll(buyTemp);
			}

			sellTemp.clear();
			buyTemp.clear();
		}
	}

	@Override
	public boolean update(OrderPairs orderPairs) {
		orderPairs.getSeller().update(orderPairs.getAmount());
		orderPairs.getBuyer().update(orderPairs.getAmount());
		pairses.add(orderPairs);
		pairsDone(orderPairs);
		return true;
	}

	@Override
	public boolean remove(Order order) {
		boolean r = false;
		synchronized (lock1) {
			if(MatchTradeConstants.ORDER_DIRECTION_SELL == order.getDirection()){
				r = sell.remove(order);
			}else if(MatchTradeConstants.ORDER_DIRECTION_BUY == order.getDirection()){
				r = buy.remove(order);
			}
		}

		if (r)	{
			history.add(order);
			finish(order);
		}
		return r;
	}

	@Override
	public Order firstSell() {
		return null;
	}

	@Override
	public Order firstBuy() {
		return null;
	}

	@Override
	public Iterator<Order> sellOrders() {
		return sell.iterator();
	}

	@Override
	public Iterator<Order> buyOrders() {
		return buy.iterator();
	}

	@Override
	public Iterator<OrderPairs> orderPairs() {
		return pairses.iterator();
	}

}
